import 'dart:async';

import 'package:ac/common/ac_pv_manager.dart';
import 'package:ac/data/ac_user_manager.dart';
import 'package:ac/model/ac_goods_model.dart';
import 'package:ac/page/ac_me/ac_me_logic.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import 'package:in_app_purchase/in_app_purchase.dart';

import '../../api/ac_urls.dart';
import 'ac_goods_state.dart';

class AcGoodsLogic extends GetxController {
  final AcGoodsState state = AcGoodsState();

  late StreamSubscription<List<PurchaseDetails>> _subscription;


  String? orderNo;

  List<ProductDetails> _products = [];

  @override
  void onInit() {
    // TODO: implement onInit
    super.onInit();
    LogPvManger.stat(page: LogPages.purchasePage);
    _initUserInfo();
    _initGoodsList();
  }
  Future<void> _listenToPurchaseUpdated(List<PurchaseDetails> purchaseDetailsList) async {
    for (var purchaseDetails in purchaseDetailsList) {
      if (purchaseDetails.status == PurchaseStatus.pending) {
        EasyLoading.show(
            status: 'purchasing...',
            maskType: EasyLoadingMaskType.black,
            dismissOnTap: false);
      } else {
        if (purchaseDetails.status == PurchaseStatus.error) {
          orderNo = null;
          EasyLoading.showToast('Purchase failed');
          EasyLoading.dismiss();
        } else if (purchaseDetails.status == PurchaseStatus.purchased ||
            purchaseDetails.status == PurchaseStatus.restored) {
          var res = await AcUrls.checkOrder.post(
            data: {
              "orderNo": orderNo,
              "payload": purchaseDetails.verificationData.serverVerificationData,
              "transactionId": purchaseDetails.purchaseID,
              "type": 1
            },
            showLoading: true,
            showErrorMessage: false,
          );
          if (res?["code"] == 0) {
            orderNo = null;
            await _initUserInfo();
            Get.find<AcMeLogic>().userInfo.value =
                AcUserManager.userInfoModel!.userInfo;
            Get.find<AcMeLogic>().userInfo.refresh();
          }
          EasyLoading.dismiss();
        } else if (purchaseDetails.status == PurchaseStatus.canceled) {
          orderNo = null;
          EasyLoading.showToast('Purchase canceled');
          EasyLoading.dismiss();
        }
        if (purchaseDetails.pendingCompletePurchase) {
          await InAppPurchase.instance
              .completePurchase(purchaseDetails);
        }
      }
    }
  }
  @override
  void onClose() {
    _subscription.cancel();
    super.onClose();
  }

  Future<void> _initUserInfo() async {
    state.userInfo.value = AcUserManager.userInfoModel!.userInfo;
    await AcUserManager.updateUserInfoFromRemote();
    state.userInfo.value = AcUserManager.userInfoModel!.userInfo;
  }

  Future<void> _initGoodsList() async {
    var res = await AcUrls.goodsList.post(
      data: {
        "isIncludeSubscription": false,
        "payChannel": "IAP",
      },
      showLoading: false,
    );
    if (res?["code"] == 0) {
      List list = res?["data"];
      state.goodsList.value =
          list.map((e) => AcGoodsModel.fromJson(e)).toList();
      state.goodsList.refresh();
      await _initPurchase();
      // Set literals require Dart 2.2. Alternatively, use
// `Set<String> _kIds = <String>['product1', 'product2'].toSet()`.
      Set<String> kIds = state.goodsList.map((element) => element.code!).toSet();
      final ProductDetailsResponse response =
      await InAppPurchase.instance.queryProductDetails(kIds);
      if (response.notFoundIDs.isNotEmpty) {
        // Handle the error.
      }
      _products = response.productDetails;
      debugPrint('products: $_products');
    }
  }

  Future<void> _initPurchase() async {
    final Stream<List<PurchaseDetails>> purchaseUpdated =
        InAppPurchase.instance.purchaseStream;
    _subscription = purchaseUpdated.listen((purchaseDetailsList) {
      _listenToPurchaseUpdated(purchaseDetailsList);
    }, onDone: () {
      _subscription.cancel();
    }, onError: (error) {
      // handle error here.
    });
  }

  Future<void> buyGoods(AcGoodsModel model) async {
    LogPvManger.stat(page: LogPages.createOrderPage);
    var res = await AcUrls.createOrder.post(
      data: {
        "entry": "",
        "source": "",
        "payChannel": "IAP",
        "goodsCode": model.code
      },
      showLoading: true,
    );
    if (res?["code"] == 0) {
      orderNo = res?["data"]["orderNo"];
      EasyLoading.show(
          status: 'loading...',
          maskType: EasyLoadingMaskType.black,
          dismissOnTap: false);
      var firstWhereOrNull = _products.firstWhereOrNull((element) => element.id == model.code);
      if(firstWhereOrNull == null){
        return;
      }
      final PurchaseParam purchaseParam = PurchaseParam(productDetails: firstWhereOrNull);
      InAppPurchase.instance.buyConsumable(purchaseParam: purchaseParam);

    }
  }
}
